package com.zch.utils.webHook.alarm;

import okhttp3.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 测试见WebhookAlarmTest
 * 给i讯飞群（以群机器人的方式）发送消息的类
 */
public class WebHookNotifier {
    private static final Logger logger = LoggerFactory.getLogger(WebHookNotifier.class);
    private static final OkHttpClient HTTP_CLIENT = new OkHttpClient();
    private static final int DEFAULT_MAX_RETRIES = 3;

    // 自定义命名线程池（核心线程数=1，最大线程数=1，队列无界）
    private static final ExecutorService THREAD_POOL = new ThreadPoolExecutor(
            1, 1, 0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(),
            new NamedThreadFactory("webhook-alarm-notifier")
    );
    /**
     * 异步发送消息（默认重试 3 次）
     */
    public static void sendAsync(AbstractAlarmMarkdown alarmMarkdown) {
        String webHookUrl = alarmMarkdown.getWebHookUrl();
        String markdownMessage = WebHookMessageTemplate.createMarkdownMessage(alarmMarkdown);
        if(StringUtils.isNotBlank(markdownMessage) && StringUtils.isNotBlank(webHookUrl)){
            sendAsync(webHookUrl,markdownMessage, DEFAULT_MAX_RETRIES);
        }
    }

    /**
     * 异步发送消息（默认重试 3 次）
     */
    public static void sendAsync(String webhookUrl, String messageJson) {
        sendAsync(webhookUrl, messageJson, DEFAULT_MAX_RETRIES);
    }

    /**
     * 异步发送消息（自定义重试次数）
     */
    public static void sendAsync(String webhookUrl, String messageJson, int maxRetries) {
        THREAD_POOL.submit(() -> {
            try {
                sendWithRetry(webhookUrl, messageJson, maxRetries);
            } catch (Exception e) {
                logger.error("Failed to send Feishu alert after {} retries: {}", maxRetries, e.getMessage());
            }
        });
    }

    /**
     * 带重试机制的发送逻辑
     */
    private static void sendWithRetry(String webhookUrl, String messageJson, int maxRetries) {
        int attempt = 0;
        while (attempt <= maxRetries) {
            attempt++;
            try {
                Request request = new Request.Builder()
                        .url(webhookUrl)
                        .post(RequestBody.create(messageJson, MediaType.get("application/json")))
                        .build();

                try (Response response = HTTP_CLIENT.newCall(request).execute()) {
                    if (response.isSuccessful()) {
                        logger.info("Feishu alert sent successfully.");
                        return;
                    } else {
                        logger.warn("Attempt {}/{} failed. Code: {}", attempt, maxRetries, response.code());
                        if (attempt > maxRetries) {
                            throw new RuntimeException("Exceeded max retries: " + maxRetries);
                        }
                    }
                }
            } catch (IOException e) {
                logger.error("Attempt {}/{} error: {}", attempt, maxRetries, e.getMessage());
                if (attempt > maxRetries) {
                    throw new RuntimeException("Exceeded max retries: " + maxRetries, e);
                }
            }

            // 指数退避等待（1s, 2s, 4s...）
            try {
                long sleepTime = 1000 * (long) Math.pow(2, attempt);
                Thread.sleep(sleepTime);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new RuntimeException("Interrupted during retry", e);
            }
        }
    }

    /**
     * 自定义线程工厂（命名线程）
     */
    private static class NamedThreadFactory implements ThreadFactory {
        private final AtomicInteger threadCount = new AtomicInteger(0);
        private final String namePrefix;

        NamedThreadFactory(String namePrefix) {
            this.namePrefix = namePrefix;
        }

        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, namePrefix + "-" + threadCount.getAndIncrement());
        }
    }
}
